#ifndef __WIZ_TOKENIZER_RESULT_HPP__SHANHAOBO_19800429__
#define __WIZ_TOKENIZER_RESULT_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"
#include "../../Core/Container/WizDataTypeArray.hpp"

namespace Wiz
{
    namespace Tokenizer
    {
        namespace Result
        {
            class Type;
            WIZ_DECLARE(::Wiz::Tokenizer::Result::Type);

            class Type
            {
            public:
                Type() : m_OriginStr(WIZ_NULLPTR), m_OriginSize(0){}
                virtual ~Type()
                {
                    if (::Wiz::IsValidPtr(m_OriginStr))
                    {
                        delete[] m_OriginStr;
                    }
                    m_OriginStr = WIZ_NULLPTR;
                    m_OriginSize = 0;
					m_Arguments.Clear();
					m_ArgumentStarts.Clear();
                }
            public:
                ::Wiz::Bool::Type   Check(::Wiz::UInt::In Idx, ::Wiz::String::In IStr)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        return IStr.ICompare(m_Arguments[Idx]);
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Bool::Type   CheckMatchCase(::Wiz::UInt::In Idx, ::Wiz::String::In IStr)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        return IStr == m_Arguments[Idx];
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
            protected:
                ::Wiz::Bool::Type Arg(::Wiz::UInt::In Idx, ::Wiz::String::Out OStr)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        OStr = m_Arguments[Idx];
                        return ::Wiz::Bool::True;
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Bool::Type Before(::Wiz::UInt::In Idx, ::Wiz::String::Out OStr)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        ::Wiz::UInt::Type       DataStart  = m_ArgumentStarts[Idx];
                        WIZ_ASSERT(DataStart < m_OriginSize);
                        ::Wiz::String::MakeCStr(OStr, m_OriginStr, DataStart);
                        return ::Wiz::Bool::True;
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Bool::Type After(::Wiz::UInt::In Idx, ::Wiz::String::Out OStr)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        ::Wiz::Char::Ptr    DataPtr   = m_OriginStr;
                        ::Wiz::Size::Type   RealSz    = m_Arguments[Idx].Size() - (m_Arguments[Idx].GetCStr()[m_Arguments[Idx].Size()] == '\0'? 1 : 0);
                        ::Wiz::UInt::Type   DataStart = m_ArgumentStarts[Idx] + RealSz;
                        WIZ_ASSERT(DataStart < m_OriginSize);
                        ::Wiz::Utils::PtrInc(DataPtr, DataStart);
                        ::Wiz::String::MakeCStr(OStr, DataPtr, ::Wiz::USize::Type(m_OriginSize - DataStart));
                        return ::Wiz::Bool::True;
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }

                ::Wiz::Bool::Type AsInt(::Wiz::UInt::In Idx, ::Wiz::Int::Out OInt)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        OInt = ::Wiz::Cast::Lexical<::Wiz::Int::Type>(m_Arguments[Idx]);
                        return ::Wiz::Bool::True;
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Bool::Type AsReal(::Wiz::UInt::In Idx, ::Wiz::Real::Out OReal)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        OReal = ::Wiz::Cast::Lexical<::Wiz::Real::Type>(m_Arguments[Idx]);
                        return ::Wiz::Bool::True;
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
                ::Wiz::Bool::Type AsBool(::Wiz::UInt::In Idx, ::Wiz::Bool::Out OBool)
                {
                    if (this->IsValidIndex(Idx))
                    {
                        if (this->Check(Idx, ::Wiz::String::Type("true")))
                        {
                            return ::Wiz::Bool::True;
                        }
                        else if (this->Check(Idx, ::Wiz::String::Type("false")))
                        {
                            return ::Wiz::Bool::False;
                        }
                    }
                    WIZ_ASSERT(::Wiz::Bool::False);
                    return ::Wiz::Bool::False;
                }
            public:
                ::Wiz::String::Type Arg(::Wiz::UInt::In Idx)
                {
                    ::Wiz::String::Type Temp;
                    if (this->Arg(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::String::Type();
                }
                ::Wiz::String::Type Before(::Wiz::UInt::In Idx)
                {
                    ::Wiz::String::Type Temp;
                    if (this->Before(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::String::Type();
                }
                ::Wiz::String::Type After(::Wiz::UInt::In Idx)
                {
                    ::Wiz::String::Type Temp;
                    if (this->After(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::String::Type();
                }

                ::Wiz::Int::Type AsInt(::Wiz::UInt::In Idx)
                {
                    ::Wiz::Int::Type Temp;
                    if (this->AsInt(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::Int::Max;
                }
                ::Wiz::Real::Type AsReal(::Wiz::UInt::In Idx)
                {
                    ::Wiz::Real::Type Temp;
                    if (this->AsReal(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::Real::Max;
                }
                ::Wiz::Bool::Type AsBool(::Wiz::UInt::In Idx)
                {
                    ::Wiz::Bool::Type Temp;
                    if (this->AsBool(Idx, Temp))
                    {
                        return Temp;
                    }
                    return ::Wiz::Bool::False;
                }
            public:
                ::Wiz::Size::Type Num()
                {
                    WIZ_ASSERT(m_Arguments.Size() == m_ArgumentStarts.Size());
                    return m_Arguments.Size();
                }
            public:
                ::Wiz::Void::Type AddArgument(::Wiz::String::In IStr, ::Wiz::UInt::Type IStart)
                {
                    m_Arguments.PushBack(IStr);
                    m_ArgumentStarts.PushBack(IStart);
                }
                ::Wiz::Void::Type AddArgument(::Wiz::Char::ConstPtr IStr, ::Wiz::Size::In StartPos, ::Wiz::UInt::Type EndPos)
                {
                    m_Arguments.PushBack(::Wiz::String::Type());
                    ::Wiz::String::MakeCStr(m_Arguments.Back(), &IStr[StartPos], EndPos - StartPos);
                    m_ArgumentStarts.PushBack(StartPos);
                }
                ::Wiz::Void::Type SetOriginStr(::Wiz::Char::Ptr IStr, ::Wiz::Size::In ISize)
                {
                    m_OriginStr = IStr;
                    m_OriginSize = ISize;
                }
            protected:
                ::Wiz::Bool::Type IsValidIndex(::Wiz::UInt::In Idx)
                {
                    return Idx < this->Num();
                }
            protected:
                ::Wiz::Array::Type<::Wiz::String::Type> m_Arguments;
                ::Wiz::Array::Type<::Wiz::UInt::Type>   m_ArgumentStarts;
                ::Wiz::Char::Ptr						m_OriginStr;
                ::Wiz::Size::Type						m_OriginSize;
            }; /// end of class Type
        } /// end of namespace Result
    } /// end of namespace Tokenizer
} /// end of namespace Wiz

#endif /*__WIZ_TOKENIZER_RESULT_HPP__SHANHAOBO_19800429__*/
